package com.briup.security.filter;

import com.briup.security.util.JwtUtil;
import com.briup.security.util.Result;
import com.fasterxml.jackson.databind.ObjectMapper;
import org.aspectj.bridge.MessageUtil;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.security.core.userdetails.UserDetailsService;
import org.springframework.web.filter.OncePerRequestFilter;

import javax.servlet.FilterChain;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;

public class AuthenticationTokenFilter extends OncePerRequestFilter {

    private static final Logger logger = LoggerFactory.getLogger(AuthenticationTokenFilter.class);

    @Autowired
    @Qualifier("myDetailService")
    private UserDetailsService userDetailsService;

    @Autowired
    private ObjectMapper objectMapper;

    @Override
    protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain filterChain) throws ServletException, IOException {
        // 1.从请求头中获取Token
        String token = request.getHeader(JwtUtil.TOKEN_HEAD);

        //2.判断token是否为空,则请求放心，让UsernamePasswordAuthenticationFilter校验用户名密码
        if (token == null || "".equals(token)) {
            filterChain.doFilter(request,response);
            return;
        }

        try {
            //3.如果token不为空，则去校验token,
            if (JwtUtil.checkSign(token)) {
                if (request.getRequestURI().contains("/login")) {
                    filterChain.doFilter(request,response); // 如果登录请求携带token 则再去校验用户名和密码
                    return;
                }
                // 获取用户信息
                String userId = JwtUtil.getUserId(token);
                UserDetails userDetails = userDetailsService.loadUserByUsername(userId);
                /**
                 *  UsernamePasswordAuthenticationToken
                 *      这个对象使用来保存用户信息
                 *  如果SecurityContextHolder.getContext()中有该对象，那么就不需要再次校验
                 */
                UsernamePasswordAuthenticationToken authenticationToken =
                        new UsernamePasswordAuthenticationToken(userDetails, null, userDetails.getAuthorities());
                SecurityContextHolder.getContext().setAuthentication(authenticationToken);
            }
            filterChain.doFilter(request, response);
        } catch (Exception e) {
            logger.info("过滤器校验token失败");
            response.setContentType("application/json;charset=UTF-8");
            response.getWriter().write(objectMapper.writeValueAsString(Result.fail(401,"token失效")));
            return;

        }
    }
}
